/*
 * Copyright 2003 ISS.
 * The contents contained in this document may not be reproduced in any
 * form or by any means, without the written permission of ISS, other
 * than for the purpose for which it has been supplied.
 *
 */
package sg.edu.nus.iss.vmcs.system;

import java.io.IOException;

import sg.edu.nus.iss.vmcs.customer.TransactionController;
import sg.edu.nus.iss.vmcs.machinery.MachineryController;
import sg.edu.nus.iss.vmcs.maintenance.MaintenanceController;
import sg.edu.nus.iss.vmcs.store.CashStoreController;
import sg.edu.nus.iss.vmcs.store.DatabasePersistence;
import sg.edu.nus.iss.vmcs.store.DrinkStoreController;
import sg.edu.nus.iss.vmcs.store.FilePersistence;
import sg.edu.nus.iss.vmcs.store.Persistence;
import sg.edu.nus.iss.vmcs.store.PersistenceFactory;
import sg.edu.nus.iss.vmcs.store.Store;
import sg.edu.nus.iss.vmcs.store.StoreController;
import sg.edu.nus.iss.vmcs.util.VMCSException;

/**
 * This object is the main controller of the vending machine&#46; It coordinates the main operations of the VMCS&#46;
 *
 * @version 3.0 5/07/2003
 * @author Olivo Miotto, Pang Ping Li
 * @editedby A0119952X - Singleton Design Pattern
 */
public class MainController {
	private SimulationController  simulatorCtrl;
	private MachineryController   machineryCtrl= MachineryController.getInstance();
	private MaintenanceController maintenanceCtrl = MaintenanceController.getInstance();
	private CashStoreController       cashStoreCtrl;
	private DrinkStoreController       drinksStoreCtrl;

	private String      propertyFile;

    private static MainController instance;
    private MainController() {
        super();
    }

    public static MainController getInstance() {
        if (instance == null) {
            instance = new MainController();
        }
        return instance;
    }

	/**
	 * This method will initiate the creation of all the control objects necessary for
	 * simulation of the vending machine, and initiate the display of the SimulatorControlPanel
	 * (the main menu).
	 * @throws VMCSException if fail to initialize.
	 */
	public void start() throws VMCSException {
		try {
			initialize();
			simulatorCtrl.displaySimulatorControlPanel();
			simulatorCtrl.setSimulationActive(false);
		} catch (VMCSException e) {
			throw new VMCSException(e);
		}
	}

	/**
	 * This method creates all the control objects.
	 * @throws VMCSException if fail to load drinks properties or cash properties.
	 */
	public void initialize() throws VMCSException {
		try {
			Environment.initialize(propertyFile);
            CashPropertyLoader cashLoaderNew = new CashPropertyLoader();
            cashLoaderNew.initialize();
            cashStoreCtrl = CashStoreController.getInstance();
            cashStoreCtrl.setPropertyLoader(cashLoaderNew);

            DrinkPropertyLoader drinkLoaderNew = new DrinkPropertyLoader();
            drinkLoaderNew.initialize();
            drinksStoreCtrl = DrinkStoreController.getInstance();
            drinksStoreCtrl.setPropertyLoader(drinkLoaderNew);

			simulatorCtrl = SimulationController.getInstance();
            simulatorCtrl.setScp(new SimulatorControlPanel());
		} catch (IOException e) {
			throw new VMCSException(
				"MainController.initialize",
				e.getMessage());
		}
	}

	/**
	 * This method destroys all the object instances created for opening the vending
	 * machine&#46; It will instruct the SimulationController to close down (by closing
	 * down all the vending machine panels) and the TransactionController to close
	 * down&#46; It will also close down other control objects and the entity objects
	 * created for simulating the vending machine&#46;
	 */
	public void closeDown() {
		try {
			cashStoreCtrl.closeDown();
		} catch (Exception e) {
			System.out.println("Error closing down the cash store: " + e);
		}
		
		try {
			drinksStoreCtrl.closeDown();
		} catch (Exception e) {
			System.out.println("Error closing down the drinks store: " + e);
		}
		machineryCtrl.closeDown();
		maintenanceCtrl.closeDown();
		simulatorCtrl.closeDown();
	}

    public void setPropertyFile(String propertyFile) {
        this.propertyFile = propertyFile;
    }

    public String getPropertyFile() {
        return propertyFile;
    }
}//End of class MainController